package org.jawa.exam;

import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.jawa.core.cache.Cache;
import org.jawa.core.cache.CacheFactory;
import org.jawa.core.util.ClassUtils;
import org.jawa.core.util.JawaGlobals;
import org.jawa.exam.model.Exam;
import org.jawa.user.DefaultUserProvider;
import org.jawa.user.User;
import org.jawa.user.UserProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExamManager {
	private static final Logger Log = LoggerFactory.getLogger(ExamManager.class);

	private ExamProvider provider;
	
	// 单一实例.
	private static class ExamManagerContainer {
		private static ExamManager instance = new ExamManager();
	}
	
	public static ExamProvider getExamProvider(){
		return ExamManagerContainer.instance.provider;
	}
	
	public static ExamManager getInstance(){
		return ExamManagerContainer.instance;
	}
	
	private Cache<Long,Exam> examCache;
	
	private ExamManager(){
		examCache=CacheFactory.createCache("exam");
		initProvider();
	}
	
	/**
	 * 初始化操作
	 */
	private void initProvider() {
		JawaGlobals.getProperty("provider.exam.className");

		String className = JawaGlobals.getProperty("provider.exam.className", "org.jawa.exam.DefaultExamProvider");
		if (provider == null || !className.equals(provider.getClass().getName())) {
			try {
				Class c = ClassUtils.forName(className);
				provider = (ExamProvider) c.newInstance();
			} catch (Exception e) {
				Log.error("不能加载用户操作的提供类: " + className, e);
				provider = new DefaultExamProvider();
			}
		}
	}
	
	/**
	 * 创建考试信息.
	 * 
	 * @param Exam 考试信息.
	 * @return 创建好的考试信息实例.
	 * @throws Exception 创建考试信息异常.
	 */
	public Exam createExam(Exam exam) throws Exception {
		if (null == exam) {
			throw new NullPointerException("用户不可以为空！");
		}

		if (null == exam.getExamId()) {
			throw new IllegalArgumentException("用户  userId 不可以为空！");
		}

		exam = provider.createExam(exam);
		examCache.put(exam.getExamId(), exam);
		return exam;
	}
	
	/**
	 * 删除考试信息。
	 * 
	 * @param ExamID
	 *            要删除考试信息的 ExamID.
	 * 
	 */
	public void deleteExam(Long examID){
		try{
			provider.deleteExam(examID);
			examCache.remove(examID);
		}catch(Exception e){
			Log.error("删除编号为{0}考试时出错!",examID);
		}
	}
	
	/**
	 * 返回总的考试信息数.
	 * 
	 * @return 总的考试信息数.
	 * 
	 */
	public int getExamCount(){
		return provider.getExamCount();
	}
	
	/**
	 * 返回系統中所有考试信息的 ExamId.
	 * 
	 * @return 不可以修改的系統中考试信息的 ExamId集合.
	 * 
	 */
	public Collection<Long> getExamIds(){
		return provider.getExamIds();
	}
	
	/**
	 * 返回所有的考试信息（考试信息集合）,{@link ExamCollection} 集合用于协助这个返回结果，他需要一个Long[] Examid
	 * 的数组，在实际需要数据的时候再{@link ExamManager#getExam()}进行查询实际数据.
	 * 
	 * @return 不可以修改的考试信息集合.
	 */
	public Collection<Exam> getExams(){
		return provider.getExams();
	}
	
	/**
	 * 返回所有的考试信息（考试信息集合）,{@link ExamCollection} 集合用于协助这个返回结果，他需要一个Long[] Examid
	 * 的数组，在实际需要数据的时候再{@link ExamManager#getExam()}进行查询实际数据.
	 * 
	 * @param startIndex
	 *            起始索引.
	 * @param numResults
	 *            要显示的考试信息数据数量.
	 * @return 不可以修改的考试信息集合.
	 * 
	 */
	public Collection<Exam> getExams(int startIndex, int numResults){
		return provider.getExams(startIndex, numResults);
	}
	
	/**
	 * 根据查询条件查询符合条件的的考试信息信息。
	 * 
	 * @param fieldQuerys
	 *            要查询的条件信息.
	 * 
	 * @return 查询到的考试信息信息结果.
	 * 
	 */
	public Collection<Exam> findExams(List<String> fields, List<String> querys){
		return provider.findExams(fields, querys);
	}
	
	/**
	 * 根据考试信息编号获取对象
	 * @param examId 考试信息编号
	 * @return 返回获取的对象实例
	 */
	public Exam loadByExamId(Long examId){
		Exam exam = examCache.get(examId);
		if (exam == null) {
			synchronized (examId) {
				exam = examCache.get(examId);
				if (exam == null) {
					exam = provider.loadByExamId(examId);
					examCache.put(exam.getExamId(), exam);
				}
			}
		}
		return exam;
	}
}
